package com.demo.connectdbtest.module.ssh.controller;

import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.SCPOutputStream;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SFTPv3Client;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

@RestController
@RequestMapping("/connect")
@Slf4j
public class ConnectController {


    /**
     * test success
     *
     * @return
     */
    @GetMapping("/connect")
    public String connect() {
        int ret = -1;
//          创建远程连接，默认连接端口为22，如果不使用默认，可以使用方法
        //new Connection(ip, port)创建对象
        String ip = "10.252.176.46";
        String user = "root";
        Integer port = 22;
        String password = "Anjian@20230411^";
        //本地文件的路径
        String localFilePath = "D:\\workData\\pythonProject\\20230913project\\traffic_brain\\shell\\jacoco_dev.sh";
        //远程服务器上存储文件的路径
        String remoteFilePath = "/data/learn/jacoco_dev.sh";

        String localJarFilePath = "D:\\data\\testJacoco\\jacococli.jar";
        String remoteJarFilePath = "/data/learn/jacococli.jar";

        String localJarFilePathTwo = "D:\\data\\testJacoco\\jacocoagent.jar";
        String remoteJarFilePathTwo = "/data/learn/jacocoagent.jar";

        /**
         * 远程的路径不存在则要创建
         */
        Connection conn = new Connection(ip);
        try {
            JSch jsch = new JSch();
            com.jcraft.jsch.Session jschSession = jsch.getSession(user, ip, port);
            jschSession.setPassword(password);
            jschSession.setConfig("StrictHostKeyChecking", "no"); // Disable host key checking
            jschSession.connect();
            ChannelSftp channelSftp = (ChannelSftp) jschSession.openChannel("sftp");
            channelSftp.connect();
            channelSftp.put(localFilePath, remoteFilePath);
            channelSftp.put(localJarFilePathTwo, remoteJarFilePathTwo);
            channelSftp.put(localJarFilePath, remoteJarFilePath);
            String sourceFilePath = remoteJarFilePath;
            String storageFilePath = "D:\\data\\logs";
            channelSftp.get(sourceFilePath, storageFilePath);

            System.out.println("上传文件完毕");
            channelSftp.disconnect();
//            jschSession.disconnect();

            String command = "sh /data/learn/jacoco_dev.sh practice-demo-3.0 /data/learn/demo/jacoco-file/1017-3.exec";
            Channel channel = jschSession.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);

            InputStream in = channel.getInputStream();
            channel.connect();

            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            while (true) {
                String line = br.readLine();
                if (line == null) {
                    break;
                }
                System.out.println(line);

            }
            /*byte[] tmp = new byte[1024];
            while (true) {
                int i = in.read(tmp, 0, 1024);
                if (i < 0) break;
                System.out.print(new String(tmp, 0, i));
            }*/





           /* //连接远程服务器
            conn.connect();
            //使用用户名和密码登录
            boolean connectFlag = conn.authenticateWithPassword(user, password);
            if (connectFlag == false) {
                throw new IOException("连接失败！");
            }

            //在connection中打开一个新的会话
            Session session = conn.openSession();
            String command = "sh /data/learn/jacoco_dev.sh practice-demo-3.0 /data/learn/demo/jacoco-file/1017-2.exec";
            //在远程服务器上执行linux指令
            session.execCommand(command);
            //指令执行结束后的输出
            InputStream stdOut = new StreamGobbler(session.getStdout());
            //指令执行结束后的错误
            InputStream stdErr = new StreamGobbler(session.getStderr());
            //然后将流对象读取出来
            BufferedReader br = new BufferedReader(new InputStreamReader(stdOut));
            BufferedReader er = new BufferedReader(new InputStreamReader(stdErr));
            while (true) {
                String line = br.readLine();
                if (line == null) {
                    break;
                }
                System.out.println(line);

            }

            //原文链接：https://blog.csdn.net/cxy_t/article/details/112983289
            //等待指令执行结束
            long TIME_OUT = 3000L;
            session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);
            //取得指令执行结束后的状态
            ret = session.getExitStatus();
            session.close();
            conn.close();*/

            Channel channelSecond = jschSession.openChannel("exec");
            ((ChannelExec) channelSecond).setCommand("docker ps");
            channelSecond.setInputStream(null);
            ((ChannelExec) channelSecond).setErrStream(System.err);

            InputStream secondInputStream = channelSecond.getInputStream();
            channelSecond.connect();

            BufferedReader secondBufferedReader = new BufferedReader(new InputStreamReader(secondInputStream));
            while (true) {
                String line = secondBufferedReader.readLine();
                if (line == null) {
                    break;
                }
                System.out.println("第二个命令的输出:" + line);

            }

            channelSecond.disconnect();
            channel.disconnect();
            jschSession.disconnect();

        } catch (Exception e) {
            System.err.printf("用户%s密码%s登录服务器%s失败！", "root", "Anjian@20230411^", "10.252.176.46");
            e.printStackTrace();
        }

        //原文链接：https://blog.csdn.net/awodewen/article/details/108119096
        return "执行完毕";
    }


    /**
     * 执行脚本
     *
     * @param conn Connection对象
     * @param cmds 要在linux上执行的指令
     */
    public int exec(Connection conn, String cmds) {
        InputStream stdOut = null;
        InputStream stdErr = null;
        int ret = -1;
        try {
            //在connection中打开一个新的会话
            Session session = conn.openSession();
            //在远程服务器上执行linux指令
            session.execCommand(cmds);
            //指令执行结束后的输出
            stdOut = new StreamGobbler(session.getStdout());
            //指令执行结束后的错误
            stdErr = new StreamGobbler(session.getStderr());
            //等待指令执行结束
            long TIME_OUT = 3000L;
            session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);
            //取得指令执行结束后的状态
            ret = session.getExitStatus();

            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ret;
    }

    public static void main(String[] args) {
        String executeCmd = "";
        Thread thread = new Thread(() -> {
            log.info("执行thread线程任务");
            Process result = null;
            try {
                result = Runtime.getRuntime().exec(String.valueOf(executeCmd));
                log.info("已执行克隆仓库的命令");
            } catch (IOException e) {
                e.printStackTrace();
            }
            InputStream inputStream = result.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String strInput;
            while (true) {
                try {
                    if (!StringUtils.isEmpty(strInput = bufferedReader.readLine())) {
                        log.info("克隆操作的输出信息：{}", strInput);
                    } else {
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }


    @GetMapping("/clone")
    public String cloneGit() throws Exception {
        new GitUtil().clone("6d0f7f04f04526e478ea56d1fe096cad027f091d");
        return "executed";
    }


}
